#ifndef _SCINTILLA_WIN_H
#define _SCINTILLA_WIN_H
#include "scintilla.h"
#include "yawl.h"
#include <string>
using std::string;

const int BOOKMARK = 1, BREAKPOINT = 2, EXEC_POINT = 3;
const long CURRENT_POS = -1;
const int C_PREPROCESSOR = 1,
          C_STRING = 2,
          C_COMMENT = 4;

char** source_extensions();
char** header_extensions();

bool is_cpp_source_ext(string ext);
bool is_cpp_header_ext(string ext);
bool is_cpp_ext(string ext);

class ScintillaWin: public TControl {
private:
  bool m_showing_lines, m_folding, m_modified;
  int m_bookmarks;
public:
  ScintillaWin(TWin *parent);

  void set_text(const char* txt)
  { send_msg(SCI_SETTEXT,0,(long)txt);  }

  int length()
  { return send_msg(SCI_GETLENGTH);  }

  int line_count()
  { return send_msg(SCI_GETLINECOUNT); }

  void set_margin_width(int mi, int w)
  {  send_msg(SCI_SETMARGINWIDTHN,mi,w); }

  bool modified() { return m_modified; }
  bool modified(bool yesno);

  char* get_text();
  int   get_text(long start, long end, char* buff);
  char* get_text_lines(int l1, int l2);
  bool load_file(const char* path, long pos = 0);
  bool save_file(const char* path, long pos = 0);
  void set_lexer(const char* path);

  void get_selection_text(const char* buff)
  { send_msg(SCI_GETSELTEXT,0,(long)buff); }

  void add_text(const char* buff, int sz)
  { send_msg(SCI_ADDTEXT,sz,(long)buff); }

  void append_text(const char* buff, int sz)
  { send_msg(SCI_APPENDTEXT,sz,(long)buff); }

  void insert_text(const char* buff, long pos)
  { send_msg(SCI_INSERTTEXT,pos,(long)buff); }

  void replace_selection(const char* buff)
  { send_msg(SCI_REPLACESEL,0,(long)buff); }

  void clear_all()
  { send_msg(SCI_CLEARALL); }
  
  // intended for the keyboard action messages
  void action(int msg)
  { send_msg(msg); }

 // editing

  void cut()       { send_msg(SCI_CUT); }
  void copy()      { send_msg(SCI_COPY); }
  void paste()     { send_msg(SCI_PASTE); }
  void undo()      { send_msg(SCI_UNDO);  }
  void redo()      { send_msg(SCI_REDO);  }
  void select_all() { send_msg(SCI_SELECTALL); }
  void clear()     { send_msg(SCI_CLEAR); }

 // position
  long pos()
  { return send_msg(SCI_GETCURRENTPOS); }

  long sel_start()
  { return send_msg(SCI_GETSELECTIONSTART); }

  long sel_end()
  { return send_msg(SCI_GETSELECTIONEND); }

  int line_from_pos(long p) // we're dealing with line nos starting at 1
  { return send_msg(SCI_LINEFROMPOSITION, p) + 1; }

  int col_from_pos(long p)
  { return send_msg(SCI_GETCOLUMN,p); }

  int current_line() 
  { return line_from_pos(pos());  }

  int current_column() // ditto for column
  {  return send_msg(SCI_GETCOLUMN, pos()) + 1;   }

  int goto_position(long pos)
  { return send_msg(SCI_GOTOPOS, pos); }

  void set_selection(long start, long end)
  { send_msg(SCI_SETSEL,start,end);  }

  int line_length(int line)
  { return send_msg(SCI_LINELENGTH,line-1);  }

  int get_line(int line, char* buff)
  { return send_msg(SCI_GETLINE,line-1,(long)buff);  }

  int get_current_line(char* buff, int sz)
  { return send_msg(SCI_GETCURLINE,sz,(long)buff); }

  long get_pos_of_line_start(int l)
  { return send_msg(SCI_POSITIONFROMLINE,l-1); }

  long get_pos_of_line_end(int l)
  { return send_msg(SCI_GETLINEENDPOSITION,l-1); }

  long get_pos_from_mouse(int x, int y)
  { return send_msg(SCI_POSITIONFROMPOINT,x,y); }

  int  get_style_at(long pos)
  { return send_msg(SCI_GETSTYLEAT,pos); }

  int brace_match(long pos)
  { return send_msg(SCI_BRACEMATCH,pos); }

  void zoom_in()
  { send_msg(SCI_ZOOMIN); }

  void zoom_out()
  { send_msg(SCI_ZOOMOUT); }

  void show_call_tip(long pos, const char* str)
  { send_msg(SCI_CALLTIPSHOW,pos,(long)str); }

  void cancel_call_tip()
  { send_msg(SCI_CALLTIPCANCEL); }

  int  goto_line(int l);
  long matching_brace();
  bool has_marker(int ms, int line);
  bool add_marker(int ms, bool do_toggle);
  bool next_marker(int ms, bool do_cycle);
  bool last_marker(int ms);
  bool delete_marker(int ms, int line);
  int  fetch_markers(int ms, int markers[]);

  void set_prop(const char *k, const char *val)
  { send_msg(SCI_SETPROPERTY,(long)k,(long)val); }
  
  int get_fold_level(int l);
  bool blank_line(int l);
  void set_line_numbers(bool yesno);
  bool get_line_numbers() { return m_showing_lines; }
  void set_folding(bool yesno);
  bool get_folding()      { return m_folding; }
  void current_word(std::string& s, long pos = -999);
  bool style_matches(long p, int style_bits);

  void style_colour(int style, long colour, bool fore = true);
  int init();
  bool find(std::string text, int flags);

};
#endif

